--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LXMF/LXMRouter.py 0.2.3 (fc4e30d4) Text, 60.28 KB
Tff7b72import T7ee787os
Tff7b72import T7ee787time
Tff7b72import T7ee787random
Tff7b72import T7ee787atexit
Tff7b72import T7ee787threading
Tff7b72import T7ee787RNS
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787umsgpack Tff7b72as T7ee787msgpack
Tff7b72from T7ee787.T7ee787LXMF Tff7b72import Te6edf3APP_NAME
Tff7b72from T7ee787.T7ee787LXMPeer Tff7b72import Te6edf3LXMPeer
Tff7b72from T7ee787.T7ee787LXMessage Tff7b72import Te6edf3LXMessage
Tff7b72from T7ee787.T7ee787Handlers Tff7b72import Te6edf3LXMFDeliveryAnnounceHandler
Tff7b72from T7ee787.T7ee787Handlers Tff7b72import Te6edf3LXMFPropagationAnnounceHandler
Tff7b72class T56d364LXMRouterTb4b4b4:
Te6edf3MAX_DELIVERY_ATTEMPTS Tff7b72= T79c0ff4
Te6edf3PROCESSING_INTERVAL Tff7b72= T79c0ff5
Te6edf3DELIVERY_RETRY_WAIT Tff7b72= T79c0ff12
Te6edf3PATH_REQUEST_WAIT Tff7b72= T79c0ff5
Te6edf3LINK_MAX_INACTIVITY Tff7b72= T79c0ff10Tff7b72*T79c0ff60
Te6edf3MESSAGE_EXPIRY Tff7b72= T79c0ff30Tff7b72*T79c0ff24Tff7b72*T79c0ff60Tff7b72*T79c0ff60
Te6edf3NODE_ANNOUNCE_DELAY Tff7b72= T79c0ff20
Te6edf3AUTOPEER Tff7b72= Tff7b72True
Te6edf3AUTOPEER_MAXDEPTH Tff7b72= T79c0ff4
Te6edf3PR_PATH_TIMEOUT Tff7b72= T79c0ff10
Te6edf3PR_IDLE Tff7b72= T79c0ff0x00
Te6edf3PR_PATH_REQUESTED Tff7b72= T79c0ff0x01
Te6edf3PR_LINK_ESTABLISHING Tff7b72= T79c0ff0x02
Te6edf3PR_LINK_ESTABLISHED Tff7b72= T79c0ff0x03
Te6edf3PR_REQUEST_SENT Tff7b72= T79c0ff0x04
Te6edf3PR_RECEIVING Tff7b72= T79c0ff0x05
Te6edf3PR_RESPONSE_RECEIVED Tff7b72= T79c0ff0x06
Te6edf3PR_COMPLETE Tff7b72= T79c0ff0x07
Te6edf3PR_NO_IDENTITY_RCVD Tff7b72= T79c0ff0xf0
Te6edf3PR_NO_ACCESS Tff7b72= T79c0ff0xf1
Te6edf3PR_ALL_MESSAGES Tff7b72= T79c0ff0x00
T8b949e### Developer-facing API ##############################
T8b949e#######################################################
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identity Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3storagepath Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3autopeer Tff7b72= Te6edf3AUTOPEERTb4b4b4, Te6edf3autopeer_maxdepth Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3randomTff7b72.Td2a8ffseedTb4b4b4(Te6edf3osTff7b72.Td2a8ffurandomTb4b4b4(T79c0ff10Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpending_inbound Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffpending_outbound Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8fffailed_outbound Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffdirect_links Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffdelivery_destinations Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffprioritised_list Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffignored_list Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffallowed_list Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffauth_required Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprocessing_outbound Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprocessing_inbound Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffpropagation_node Tff7b72= Tff7b72False
Tff7b72if Te6edf3storagepath Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffLXMF cannot be initialised without a storage pathTa5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstoragepath Tff7b72= Te6edf3storagepathTff7b72+Ta5d6ff"Ta5d6ff/lxmfTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffinformation_storage_limit Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_from Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_to Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_IDLE
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= T79c0ff0.0
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_last_result Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messages Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_ids Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3identity Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Te6edf3identity
Tff7b72selfTff7b72.Td2a8fflxmf_query_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffPLAINTb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffqueryTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpropagationTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3autopeer Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffautopeer Tff7b72= Te6edf3autopeer
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffautopeer Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffAUTOPEER
Tff7b72if Te6edf3autopeer_maxdepth Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffautopeer_maxdepth Tff7b72= Te6edf3autopeer_maxdepth
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffautopeer_maxdepth Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffAUTOPEER_MAXDEPTH
Tff7b72selfTff7b72.Td2a8ffpeers Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffpropagation_entries Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffpropagated_ids Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffregister_announce_handlerTb4b4b4(Te6edf3LXMFDeliveryAnnounceHandlerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffregister_announce_handlerTb4b4b4(Te6edf3LXMFPropagationAnnounceHandlerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__delivery_callback Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/local_deliveriesTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3locally_delivered_file Tff7b72= Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/local_deliveriesTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3locally_delivered_fileTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_ids Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3locally_delivered_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffclean_transient_id_cacheTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not load locally delivered message ID cache from storage. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3atexitTff7b72.Td2a8ffregisterTb4b4b4(Tff7b72selfTff7b72.Td2a8ffexit_handlerTb4b4b4)
Te6edf3job_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffjobloopTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffsetDaemonTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffannounceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffdelivery_destinationsTb4b4b4:
Te6edf3delivery_destination Tff7b72= Tff7b72selfTff7b72.Td2a8ffdelivery_destinationsTb4b4b4[Te6edf3destination_hashTb4b4b4]
Te6edf3delivery_destinationTff7b72.Td2a8ffannounceTb4b4b4(Te6edf3delivery_destinationTff7b72.Td2a8ffdisplay_nameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffannounce_propagation_nodeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffdelayed_announceTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Te6edf3LXMRouterTff7b72.Td2a8ffNODE_ANNOUNCE_DELAYTb4b4b4)
Te6edf3data Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tb4b4b4[Tff7b72selfTff7b72.Td2a8ffpropagation_nodeTb4b4b4, Tffa657intTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_destinationTff7b72.Td2a8ffannounceTb4b4b4(Te6edf3app_dataTff7b72=Te6edf3dataTb4b4b4)
Te6edf3da_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3delayed_announceTb4b4b4)
Te6edf3da_threadTff7b72.Td2a8ffsetDaemonTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3da_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffregister_delivery_identityTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identityTb4b4b4, Te6edf3display_name Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3delivery_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Ta5d6ff"Ta5d6fflxmfTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdeliveryTa5d6ff"Tb4b4b4)
Te6edf3delivery_destinationTff7b72.Td2a8ffset_packet_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdelivery_packetTb4b4b4)
Te6edf3delivery_destinationTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdelivery_link_establishedTb4b4b4)
Te6edf3delivery_destinationTff7b72.Td2a8ffdisplay_name Tff7b72= Te6edf3display_name
Tff7b72if Te6edf3display_name Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3delivery_destinationTff7b72.Td2a8ffset_default_app_dataTb4b4b4(Te6edf3display_nameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdelivery_destinationsTb4b4b4[Te6edf3delivery_destinationTff7b72.Td2a8ffhashTb4b4b4] Tff7b72= Te6edf3delivery_destination
Tff7b72return Te6edf3delivery_destination
Tff7b72def Td2a8ffregister_delivery_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__delivery_callback Tff7b72= Te6edf3callback
Tff7b72def Td2a8ffset_outbound_propagation_nodeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8 Tff7b72or Tffa657typeTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72!= Tffa657bytesTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid destination hash for outbound propagation nodeTa5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node Tff7b72= Te6edf3destination_hash
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhash Tff7b72!= Te6edf3destination_hashTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Tff7b72None
Tff7b72def Td2a8ffget_outbound_propagation_nodeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node
Tff7b72def Td2a8ffset_authenticationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3requiredTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3required Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffauth_required Tff7b72= Te6edf3required
Tff7b72def Td2a8ffrequires_authenticationTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffauth_required
Tff7b72def Td2a8ffallowTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identity_hashTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3identity_hashTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3identity_hashTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3identity_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffallowed_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffallowed_listTff7b72.Td2a8ffappendTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffAllowed identity hash must be Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffdisallowTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identity_hashTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3identity_hashTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3identity_hashTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:
Tff7b72if Te6edf3identity_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffallowed_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffallowed_listTff7b72.Td2a8ffpopTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffDisallowed identity hash must be Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffprioritiseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3destination_hashTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffprioritised_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffprioritised_listTff7b72.Td2a8ffappendTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffPrioritised destination hash must be Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffunprioritiseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identity_hashTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3destination_hashTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4:
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffprioritised_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffprioritised_listTff7b72.Td2a8ffpopTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffPrioritised destination hash must be Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffrequest_messages_from_propagation_nodeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identityTb4b4b4, Te6edf3max_messages Tff7b72= Te6edf3PR_ALL_MESSAGESTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3max_messages Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3max_messages Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_ALL_MESSAGES
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messages Tff7b72= Te6edf3max_messages
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= T79c0ff0.0
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_LINK_ESTABLISHED
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffidentifyTb4b4b4(Te6edf3identityTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffrequestTb4b4b4(
Te6edf3LXMPeerTff7b72.Td2a8ffMESSAGE_GET_PATHTb4b4b4,
Tb4b4b4[Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4]Tb4b4b4,
Te6edf3response_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_list_responseTb4b4b4,
Te6edf3failed_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_get_failed
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_REQUEST_SENT
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_from Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_LINK_ESTABLISHING
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEstablishing link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for message downloadTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3propagation_node_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)
Te6edf3propagation_node_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3propagation_node_identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpropagationTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffmsg_request_established_callbackTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrequest_messages_from_propagation_nodeTb4b4b4(Te6edf3identityTb4b4b4, Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messagesTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4(Te6edf3propagation_node_destinationTb4b4b4, Te6edf3established_callbackTff7b72=Te6edf3msg_request_established_callbackTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNo path known for message download from propagation node Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. Requesting path...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_from Tff7b72= Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_to Tff7b72= Te6edf3identity
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_timeout Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffPR_PATH_TIMEOUT
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_PATH_REQUESTED
Tff7b72selfTff7b72.Td2a8ffrequest_messages_path_jobTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
T8b949e# TODO: Remove at some point
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffWaiting for propagation node link to become activeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCannot request LXMF propagation node sync, no default propagation node configuredTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72def Td2a8ffcancel_propagation_node_requestsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffacknowledge_sync_completionTb4b4b4(Te6edf3reset_stateTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffenable_propagationTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagepath Tff7b72= Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/messagestoreTa5d6ff"
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagepathTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_entries Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3filename Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagepathTb4b4b4)Tb4b4b4:
Te6edf3components Tff7b72= Te6edf3filenameTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff"Ta5d6ff_Ta5d6ff"Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3componentsTb4b4b4) Tff7b72== T79c0ff2Tb4b4b4:
Tff7b72if Tffa657floatTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3transient_id Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Te6edf3received Tff7b72= Tffa657floatTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Te6edf3filepath Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessagepathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3filename
Te6edf3msg_size Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetsizeTb4b4b4(Te6edf3filepathTb4b4b4)
Te6edf3file Tff7b72= Tffa657openTb4b4b4(Te6edf3filepathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3destination_hash Tff7b72= Te6edf3fileTff7b72.Td2a8ffreadTb4b4b4(Te6edf3LXMessageTff7b72.Td2a8ffDESTINATION_LENGTHTb4b4b4)
Te6edf3fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Tb4b4b4[
Te6edf3destination_hashTb4b4b4,
Te6edf3filepathTb4b4b4,
Te6edf3receivedTb4b4b4,
Te6edf3msg_sizeTb4b4b4,
Tb4b4b4]
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not read LXM from message store. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/peersTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3peers_file Tff7b72= Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/peersTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3peers_data Tff7b72= Te6edf3peers_fileTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3peers_dataTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3serialised_peers Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3peers_dataTb4b4b4)
Tff7b72for Te6edf3serialised_peer Tff7b72in Te6edf3serialised_peersTb4b4b4:
Te6edf3peer Tff7b72= Te6edf3LXMPeerTff7b72.Td2a8fffrom_bytesTb4b4b4(Te6edf3serialised_peerTb4b4b4, Tff7b72selfTb4b4b4)
Tff7b72if Te6edf3peerTff7b72.Td2a8ffidentity Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3peerTff7b72.Td2a8ffdestination_hashTb4b4b4] Tff7b72= Te6edf3peer
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLoaded peer Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3peerTff7b72.Td2a8ffdestination_hashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff with Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3peerTff7b72.Td2a8ffunhandled_messagesTb4b4b4)Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff unhandled messagesTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPeer Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3peerTff7b72.Td2a8ffdestination_hashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff could not be loaded, because its identity could not be recalled. Dropping peer.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_node Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffpropagation_destinationTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_link_establishedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_destinationTff7b72.Td2a8ffset_packet_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_packetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_destinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Te6edf3LXMPeerTff7b72.Td2a8ffOFFER_REQUEST_PATHTb4b4b4, Tff7b72selfTff7b72.Td2a8ffoffer_requestTb4b4b4, Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_destinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Te6edf3LXMPeerTff7b72.Td2a8ffMESSAGE_GET_PATHTb4b4b4, Tff7b72selfTff7b72.Td2a8ffmessage_get_requestTb4b4b4, Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALLTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_str Tff7b72= Ta5d6ff"Ta5d6ff, limit is Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_storage_limitTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3limit_str Tff7b72= Ta5d6ff"Ta5d6ff"
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLXMF Propagation Node message store size is Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_storage_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72+Te6edf3limit_strTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffannounce_propagation_nodeTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not enable propagation node. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72raise Te6edf3e
Te6edf3RNSTff7b72.Td2a8ffpanicTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffdisable_propagationTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_node Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffannounce_propagation_nodeTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffignore_destinationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffignored_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffignored_listTff7b72.Td2a8ffappendTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72def Td2a8ffunignore_destinationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffignored_listTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffignored_listTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72def Td2a8ffset_message_storage_limitTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3kilobytes Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3megabytes Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3gigabytes Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3limit_bytes Tff7b72= T79c0ff0
Tff7b72if Te6edf3kilobytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3kilobytesTff7b72*T79c0ff1000
Tff7b72if Te6edf3megabytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3megabytesTff7b72*T79c0ff1000Tff7b72*T79c0ff1000
Tff7b72if Te6edf3gigabytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3gigabytesTff7b72*T79c0ff1000Tff7b72*T79c0ff1000Tff7b72*T79c0ff1000
Tff7b72if Te6edf3limit_bytes Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3limit_bytes Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3limit_bytes Tff7b72== Tff7b72None Tff7b72or Tffa657intTb4b4b4(Te6edf3limit_bytesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit Tff7b72= Tffa657intTb4b4b4(Te6edf3limit_bytesTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffCannot set LXMF information storage limit to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3limit_bytesTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffCannot set LXMF information storage limit to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3limit_bytesTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffmessage_storage_limitTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit
Tff7b72def Td2a8ffmessage_storage_sizeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpropagation_nodeTb4b4b4:
Tff7b72return Tffa657sumTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3fTb4b4b4]Tb4b4b4[T79c0ff3Tb4b4b4] Tff7b72for Te6edf3f Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72def Td2a8ffset_information_storage_limitTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3kilobytes Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3megabytes Tff7b72= Tff7b72NoneTb4b4b4, Te6edf3gigabytes Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Te6edf3limit_bytes Tff7b72= T79c0ff0
Tff7b72if Te6edf3kilobytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3kilobytesTff7b72*T79c0ff1000
Tff7b72if Te6edf3megabytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3megabytesTff7b72*T79c0ff1000Tff7b72*T79c0ff1000
Tff7b72if Te6edf3gigabytes Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3limit_bytes Tff7b72+Tff7b72= Te6edf3gigabytesTff7b72*T79c0ff1000Tff7b72*T79c0ff1000Tff7b72*T79c0ff1000
Tff7b72if Te6edf3limit_bytes Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3limit_bytes Tff7b72= Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3limit_bytes Tff7b72== Tff7b72None Tff7b72or Tffa657intTb4b4b4(Te6edf3limit_bytesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffinformation_storage_limit Tff7b72= Tffa657intTb4b4b4(Te6edf3limit_bytesTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffCannot set LXMF information storage limit to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3limit_bytesTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffCannot set LXMF information storage limit to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3limit_bytesTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffinformation_storage_limitTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffinformation_storage_limit
Tff7b72def Td2a8ffinformation_storage_sizeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72pass
T8b949e### Utility & Maintenance #############################
T8b949e#######################################################
Te6edf3JOB_OUTBOUND_INTERVAL Tff7b72= T79c0ff1
Te6edf3JOB_LINKS_INTERVAL Tff7b72= T79c0ff1
Te6edf3JOB_TRANSIENT_INTERVAL Tff7b72= T79c0ff60
Te6edf3JOB_STORE_INTERVAL Tff7b72= T79c0ff120
Te6edf3JOB_PEERSYNC_INTERVAL Tff7b72= T79c0ff12
Tff7b72def Td2a8ffjobsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72+Tff7b72= T79c0ff1
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72% Te6edf3LXMRouterTff7b72.Td2a8ffJOB_OUTBOUND_INTERVAL Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffprocess_outboundTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72% Te6edf3LXMRouterTff7b72.Td2a8ffJOB_LINKS_INTERVAL Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffclean_linksTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72% Te6edf3LXMRouterTff7b72.Td2a8ffJOB_TRANSIENT_INTERVAL Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffclean_transient_id_cacheTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72% Te6edf3LXMRouterTff7b72.Td2a8ffJOB_STORE_INTERVAL Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffclean_message_storeTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_count Tff7b72% Te6edf3LXMRouterTff7b72.Td2a8ffJOB_PEERSYNC_INTERVAL Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsync_peersTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffjobloopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tb4b4b4(Tff7b72TrueTb4b4b4)Tb4b4b4:
T8b949e# TODO: Improve this to scheduling, so manual
T8b949e# triggers can delay next run
Tff7b72selfTff7b72.Td2a8ffjobsTb4b4b4(Tb4b4b4)
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Te6edf3LXMRouterTff7b72.Td2a8ffPROCESSING_INTERVALTb4b4b4)
Tff7b72def Td2a8ffclean_linksTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3closed_links Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3link_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffdirect_linksTb4b4b4:
Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8ffdirect_linksTb4b4b4[Te6edf3link_hashTb4b4b4]
Te6edf3inactive_time Tff7b72= Te6edf3linkTff7b72.Td2a8ffinactive_forTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3inactive_time Tff7b72> Te6edf3LXMRouterTff7b72.Td2a8ffLINK_MAX_INACTIVITYTb4b4b4:
Te6edf3linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Te6edf3closed_linksTff7b72.Td2a8ffappendTb4b4b4(Te6edf3link_hashTb4b4b4)
Tff7b72for Te6edf3link_hash Tff7b72in Te6edf3closed_linksTb4b4b4:
Te6edf3cleaned_link Tff7b72= Tff7b72selfTff7b72.Td2a8ffdirect_linksTff7b72.Td2a8ffpopTb4b4b4(Te6edf3link_hashTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCleaned link Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3cleaned_linkTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffCLOSEDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffacknowledge_sync_completionTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCleaned outbound propagation linkTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72def Td2a8ffclean_transient_id_cacheTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3removed_entries Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTb4b4b4:
Te6edf3timestamp Tff7b72= Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTb4b4b4[Te6edf3transient_idTb4b4b4]
Tff7b72if Te6edf3now Tff7b72> Te6edf3timestampTff7b72+Te6edf3LXMRouterTff7b72.Td2a8ffMESSAGE_EXPIRYTff7b72*T79c0ff1.25Tb4b4b4:
Te6edf3removed_entriesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3transient_idTb4b4b4)
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3removed_entriesTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTff7b72.Td2a8ffpopTb4b4b4(Te6edf3transient_idTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCleaned Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff from local delivery cacheTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72def Td2a8ffclean_message_storeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# Check and remove expired messages
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3removed_entries Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4:
Te6edf3entry Tff7b72= Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]
Te6edf3filepath Tff7b72= Te6edf3entryTb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3components Tff7b72= Te6edf3filepathTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff"Ta5d6ff_Ta5d6ff"Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3componentsTb4b4b4) Tff7b72== T79c0ff2 Tff7b72and Tffa657floatTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72> T79c0ff0 Tff7b72and Tffa657lenTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffsplitTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72== Tb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72*T79c0ff2Tb4b4b4:
Te6edf3timestamp Tff7b72= Tffa657floatTb4b4b4(Te6edf3componentsTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3now Tff7b72> Te6edf3timestampTff7b72+Te6edf3LXMRouterTff7b72.Td2a8ffMESSAGE_EXPIRYTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPurging message Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff due to expiryTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3removed_entriesTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Te6edf3filepath
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPurging message Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff due to invalid file pathTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Te6edf3removed_entriesTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Te6edf3filepath
Te6edf3removed_count Tff7b72= T79c0ff0
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3removed_entriesTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3filepath Tff7b72= Te6edf3removed_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]
Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTff7b72.Td2a8ffpopTb4b4b4(Te6edf3transient_idTb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3filepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3filepathTb4b4b4)
Te6edf3removed_count Tff7b72+Tff7b72= T79c0ff1
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not remove Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff from message store. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72if Te6edf3removed_count Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCleaned Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3removed_countTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff entries from the message storeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
T8b949e# Check size of message store and cull if needed
Tff7b72tryTb4b4b4:
Te6edf3message_storage_size Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessage_storage_sizeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3message_storage_size Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit Tff7b72!= Tff7b72None Tff7b72and Te6edf3message_storage_size Tff7b72> Tff7b72selfTff7b72.Td2a8ffmessage_storage_limitTb4b4b4:
T8b949e# Clean the message storage according to priorities
Te6edf3bytes_needed Tff7b72= Te6edf3message_storage_size Tff7b72- Tff7b72selfTff7b72.Td2a8ffmessage_storage_limit
Te6edf3bytes_cleaned Tff7b72= T79c0ff0
Te6edf3now Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3weighted_entries Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4:
Te6edf3entry Tff7b72= Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]
Te6edf3dst_hash Tff7b72= Te6edf3entryTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3lxm_rcvd Tff7b72= Te6edf3entryTb4b4b4[T79c0ff2Tb4b4b4]
Te6edf3lxm_size Tff7b72= Te6edf3entryTb4b4b4[T79c0ff3Tb4b4b4]
Te6edf3age_weight Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tb4b4b4(Te6edf3now Tff7b72- Te6edf3lxm_rcvdTb4b4b4)Tff7b72/T79c0ff60Tff7b72/T79c0ff60Tff7b72/T79c0ff24Tff7b72/T79c0ff4Tb4b4b4)
Tff7b72if Te6edf3dst_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffprioritised_listTb4b4b4:
Te6edf3priority_weight Tff7b72= T79c0ff0.1
Tff7b72elseTb4b4b4:
Te6edf3priority_weight Tff7b72= T79c0ff1.0
Te6edf3weight Tff7b72= Te6edf3priority_weight Tff7b72* Te6edf3age_weight Tff7b72* Te6edf3lxm_size
Te6edf3weighted_entriesTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4[Te6edf3entryTb4b4b4, Te6edf3weightTb4b4b4, Te6edf3transient_idTb4b4b4]Tb4b4b4)
Te6edf3weighted_entriesTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3weTb4b4b4: Te6edf3weTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Te6edf3reverseTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3i Tff7b72= T79c0ff0
Tff7b72while Te6edf3i Tff7b72< Tffa657lenTb4b4b4(Te6edf3weighted_entriesTb4b4b4) Tff7b72and Te6edf3bytes_cleaned Tff7b72< Te6edf3bytes_neededTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3w Tff7b72= Te6edf3weighted_entriesTb4b4b4[Te6edf3iTb4b4b4]
Te6edf3entry Tff7b72= Te6edf3wTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3transient_id Tff7b72= Te6edf3wTb4b4b4[T79c0ff2Tb4b4b4]
Te6edf3filepath Tff7b72= Te6edf3entryTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3filepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3filepathTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTff7b72.Td2a8ffpopTb4b4b4(Te6edf3transient_idTb4b4b4)
Te6edf3bytes_cleaned Tff7b72+Tff7b72= Te6edf3entryTb4b4b4[T79c0ff3Tb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff with weight Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3wTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to clear up Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3entryTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, now cleaned Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3bytes_cleanedTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff out of Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Te6edf3bytes_neededTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff neededTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while cleaning LXMF message from message store. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72finallyTb4b4b4:
Te6edf3i Tff7b72+Tff7b72= T79c0ff1
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLXMF message store size is now Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettysizeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_storage_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPE len Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not clean the LXMF message store. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72def Td2a8ffsave_locally_delivered_transient_idsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)
Te6edf3locally_delivered_file Tff7b72= Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/local_deliveriesTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4)
Te6edf3locally_delivered_fileTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTb4b4b4)Tb4b4b4)
Te6edf3locally_delivered_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not save locally delivered message ID cache to storage. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72def Td2a8ffexit_handlerTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpropagation_nodeTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3serialised_peers Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3peer_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3peer_idTb4b4b4]
Te6edf3serialised_peersTff7b72.Td2a8ffappendTb4b4b4(Te6edf3peerTff7b72.Td2a8ffto_bytesTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3peers_file Tff7b72= Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/peersTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4)
Te6edf3peers_fileTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3serialised_peersTb4b4b4)Tb4b4b4)
Te6edf3peers_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSaved Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3serialised_peersTb4b4b4)Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff peers to storageTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not save propagation node peers to storage. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsave_locally_delivered_transient_idsTb4b4b4(Tb4b4b4)
Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff<LXMRouter Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff>Ta5d6ff"
T8b949e### Message Download ##################################
T8b949e#######################################################
Tff7b72def Td2a8ffrequest_messages_path_jobTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3job_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ff__request_messages_path_jobTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffsetDaemonTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3job_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ff__request_messages_path_jobTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_fromTb4b4b4) Tff7b72and Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72< Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_timeoutTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_fromTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrequest_messages_from_propagation_nodeTb4b4b4(Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_toTb4b4b4, Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messagesTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation node path request timed outTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffacknowledge_sync_completionTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffidentity_allowedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3identityTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffauth_requiredTb4b4b4:
Tff7b72if Te6edf3identityTff7b72.Td2a8ffhash Tff7b72in Tff7b72selfTff7b72.Td2a8ffallowed_listTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72def Td2a8ffmessage_get_requestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3remote_identity Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_IDENTITY
Tff7b72elif Tff7b72not Tff7b72selfTff7b72.Td2a8ffidentity_allowedTb4b4b4(Te6edf3remote_identityTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_ACCESS
Tff7b72elseTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3remote_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffdeliveryTa5d6ff"Tb4b4b4)
T8b949e# If both want and have fields are empty, send a list of
T8b949e# available messages.
Tff7b72if Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Tff7b72None Tff7b72and Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3available_messages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4:
Te6edf3message_entry Tff7b72= Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]
Tff7b72if Te6edf3message_entryTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3message_size Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetsizeTb4b4b4(Te6edf3message_entryTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Te6edf3available_entry Tff7b72= Tb4b4b4[Te6edf3transient_idTb4b4b4, Te6edf3message_sizeTb4b4b4]
Te6edf3available_messagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3available_entryTb4b4b4)
Te6edf3available_messagesTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3eTb4b4b4: Te6edf3eTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Te6edf3reverseTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3transient_ids Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3available_entry Tff7b72in Te6edf3available_messagesTb4b4b4:
Te6edf3transient_idsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3available_entryTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3transient_ids
Tff7b72elseTb4b4b4:
T8b949e# Process messages the client already have
Tff7b72if Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72!= Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4:
Tff7b72if Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entries Tff7b72and Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3filepath Tff7b72= Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]Tb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTff7b72.Td2a8ffpopTb4b4b4(Te6edf3transient_idTb4b4b4)
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3filepathTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffClient Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff purged message Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff at Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3filepathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while processing message purge request from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
T8b949e# Process wanted messages
Te6edf3response_messages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72if Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72!= Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4:
Tff7b72if Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entries Tff7b72and Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]Tb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3filepath Tff7b72= Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4]Tb4b4b4[T79c0ff1Tb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffClient Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff requested message Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff at Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3filepathTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3message_file Tff7b72= Tffa657openTb4b4b4(Te6edf3filepathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3lxmf_data Tff7b72= Te6edf3message_fileTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3response_messagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Te6edf3message_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while processing message download request from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3remote_destinationTff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Te6edf3response_messages
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while generating response for download request, the contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72None
Tff7b72def Td2a8ffmessage_list_responseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72== Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_IDENTITYTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation node indicated missing identification on list request, tearing down link.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_NO_IDENTITY_RCVD
Tff7b72elif Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72== Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_ACCESSTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation node did not allow list request, tearing down link.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_NO_ACCESS
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72!= Tff7b72None Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4, Tffa657listTb4b4b4)Tb4b4b4:
Te6edf3haves Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3wants Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72if Tffa657lenTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffhas_messageTb4b4b4(Te6edf3transient_idTb4b4b4)Tb4b4b4:
Te6edf3havesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3transient_idTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messages Tff7b72== Te6edf3LXMRouterTff7b72.Td2a8ffPR_ALL_MESSAGES Tff7b72or Tffa657lenTb4b4b4(Te6edf3wantsTb4b4b4) Tff7b72< Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_max_messagesTb4b4b4:
Te6edf3wantsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3transient_idTb4b4b4)
Te6edf3request_receiptTff7b72.Td2a8fflinkTff7b72.Td2a8ffrequestTb4b4b4(
Te6edf3LXMPeerTff7b72.Td2a8ffMESSAGE_GET_PATHTb4b4b4,
Tb4b4b4[Te6edf3wantsTb4b4b4, Te6edf3havesTb4b4b4]Tb4b4b4,
Te6edf3response_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_get_responseTb4b4b4,
Te6edf3failed_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_get_failedTb4b4b4,
Te6edf3progress_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_get_progress
Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_COMPLETE
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= T79c0ff1.0
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_last_result Tff7b72= T79c0ff0
Tff7b72def Td2a8ffmessage_get_responseTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72== Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_IDENTITYTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation node indicated missing identification on get request, tearing down link.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_NO_IDENTITY_RCVD
Tff7b72elif Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72== Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_ACCESSTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation node did not allow get request, tearing down link.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_NO_ACCESS
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3request_receiptTff7b72.Td2a8ffresponse Tff7b72!= Tff7b72None Tff7b72and Tffa657lenTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3haves Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3lxmf_data Tff7b72in Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflxmf_propagationTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Te6edf3havesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3lxmf_dataTb4b4b4)Tb4b4b4)
T8b949e# Return a list of successfully received messages to the node.
T8b949e# This deletes the messages on the propagation node.
T8b949e# TODO: Add option to keep messages on node.
Te6edf3request_receiptTff7b72.Td2a8fflinkTff7b72.Td2a8ffrequestTb4b4b4(
Te6edf3LXMPeerTff7b72.Td2a8ffMESSAGE_GET_PATHTb4b4b4,
Tb4b4b4[Tff7b72NoneTb4b4b4, Te6edf3havesTb4b4b4]Tb4b4b4,
T8b949e# response_callback=self.message_syncfinal_response,
Te6edf3failed_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffmessage_get_failedTb4b4b4,
T8b949e# progress_callback=self.message_get_progress
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_COMPLETE
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= T79c0ff1.0
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_last_result Tff7b72= Tffa657lenTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffresponseTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsave_locally_delivered_transient_idsTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffmessage_get_progressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_RECEIVING
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= Te6edf3request_receiptTff7b72.Td2a8ffget_progressTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffmessage_get_failedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffMessage list/get request failedTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffacknowledge_sync_completionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3reset_stateTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3reset_state Tff7b72or Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72<Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_COMPLETETb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_state Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffPR_IDLE
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_progress Tff7b72= T79c0ff0.0
Tff7b72selfTff7b72.Td2a8ffpropagation_transfer_last_result Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_from Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffwants_download_on_path_available_to Tff7b72= Tff7b72None
Tff7b72def Td2a8ffhas_messageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3transient_idTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72False
T8b949e### Message Routing & Delivery ########################
T8b949e#######################################################
Tff7b72def Td2a8ffhandle_outboundTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3lxmessageTb4b4b4)Tb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffOUTBOUND
Tff7b72if Tff7b72not Te6edf3lxmessageTff7b72.Td2a8ffpackedTb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8ffpackTb4b4b4(Tb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffdetermine_transport_encryptionTb4b4b4(Tb4b4b4)
Tff7b72while Tff7b72selfTff7b72.Td2a8ffprocessing_outboundTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpending_outboundTff7b72.Td2a8ffappendTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffprocess_outboundTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8fflxmf_deliveryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3lxmf_dataTb4b4b4, Te6edf3destination_type Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3message Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffunpack_from_bytesTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Tff7b72if Te6edf3destination_type Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4:
Te6edf3messageTff7b72.Td2a8fftransport_encrypted Tff7b72= Tff7b72True
Te6edf3messageTff7b72.Td2a8fftransport_encryption Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffENCRYPTION_DESCRIPTION_EC
Tff7b72elif Te6edf3destination_type Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffGROUPTb4b4b4:
Te6edf3messageTff7b72.Td2a8fftransport_encrypted Tff7b72= Tff7b72True
Te6edf3messageTff7b72.Td2a8fftransport_encryption Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffENCRYPTION_DESCRIPTION_AES
Tff7b72elif Te6edf3destination_type Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffLINKTb4b4b4:
Te6edf3messageTff7b72.Td2a8fftransport_encrypted Tff7b72= Tff7b72True
Te6edf3messageTff7b72.Td2a8fftransport_encryption Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffENCRYPTION_DESCRIPTION_EC
Tff7b72elseTb4b4b4:
Te6edf3messageTff7b72.Td2a8fftransport_encrypted Tff7b72= Tff7b72False
Te6edf3messageTff7b72.Td2a8fftransport_encryption Tff7b72= Tff7b72None
Tff7b72if Te6edf3messageTff7b72.Td2a8ffsource_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffignored_listTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff ignored message from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3messageTff7b72.Td2a8ffsource_hashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72False
Tff7b72if Tff7b72selfTff7b72.Td2a8ff__delivery_callback Tff7b72!= Tff7b72None Tff7b72and Tffa657callableTb4b4b4(Tff7b72selfTff7b72.Td2a8ff__delivery_callbackTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__delivery_callbackTb4b4b4(Te6edf3messageTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error occurred in the external delivery callback for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not assemble LXMF message from received dataTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_NOTICETb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72False
Tff7b72def Td2a8ffdelivery_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3packetTff7b72.Td2a8ffdestination_type Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffLINKTb4b4b4:
Te6edf3lxmf_data Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Te6edf3lxmf_data Tff7b72+Tff7b72= Te6edf3packetTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhash
Te6edf3lxmf_data Tff7b72+Tff7b72= Te6edf3data
Tff7b72elseTb4b4b4:
Te6edf3lxmf_data Tff7b72= Te6edf3data
Tff7b72if Tff7b72selfTff7b72.Td2a8fflxmf_deliveryTb4b4b4(Te6edf3lxmf_dataTb4b4b4, Te6edf3packetTff7b72.Td2a8ffdestination_typeTb4b4b4)Tb4b4b4:
Te6edf3packetTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while parsing incoming LXMF data.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72def Td2a8ffdelivery_link_establishedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8ffset_packet_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdelivery_packetTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_strategyTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACCEPT_ALLTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_started_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffresource_transfer_beganTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_concluded_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdelivery_resource_concludedTb4b4b4)
Tff7b72def Td2a8ffdelivery_link_closedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72pass
Tff7b72def Td2a8ffresource_transfer_beganTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTransfer began for LXMF delivery resource Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72def Td2a8ffdelivery_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTransfer concluded for LXMF delivery resource Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
Tff7b72selfTff7b72.Td2a8fflxmf_deliveryTb4b4b4(Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3resourceTff7b72.Td2a8fflinkTff7b72.Td2a8fftypeTb4b4b4)
T8b949e### Peer Sync & Propagation ###########################
T8b949e#######################################################
Tff7b72def Td2a8ffpeerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3destination_hashTb4b4b4]
Te6edf3peerTff7b72.Td2a8ffalive Tff7b72= Tff7b72True
Te6edf3peerTff7b72.Td2a8ffpeering_timebase Tff7b72= Te6edf3timestamp
Te6edf3peerTff7b72.Td2a8fflast_heard Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3peer Tff7b72= Te6edf3LXMPeerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)
Te6edf3peerTff7b72.Td2a8ffalive Tff7b72= Tff7b72True
Te6edf3peerTff7b72.Td2a8fflast_heard Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3destination_hashTb4b4b4] Tff7b72= Te6edf3peer
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPeered with Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3peerTff7b72.Td2a8ffdestinationTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffunpeerTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4, Te6edf3timestamp Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3timestamp Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3timestamp Tff7b72= Tffa657intTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3destination_hashTb4b4b4]
Tff7b72if Te6edf3timestamp Tff7b72>Tff7b72= Te6edf3peerTff7b72.Td2a8ffpeering_timebaseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3destination_hashTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffBroke peering with Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3peerTff7b72.Td2a8ffdestinationTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffsync_peersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3culled_peers Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3waiting_peers Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3peer_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3peer_idTb4b4b4]
Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3peerTff7b72.Td2a8fflast_heard Tff7b72+ Te6edf3LXMPeerTff7b72.Td2a8ffMAX_UNREACHABLETb4b4b4:
Te6edf3culled_peersTff7b72.Td2a8ffappendTb4b4b4(Te6edf3peer_idTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3peerTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMPeerTff7b72.Td2a8ffIDLE Tff7b72and Tffa657lenTb4b4b4(Te6edf3peerTff7b72.Td2a8ffunhandled_messagesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3waiting_peersTff7b72.Td2a8ffappendTb4b4b4(Te6edf3peerTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3waiting_peersTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRandomly selecting peer to sync from Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3waiting_peersTb4b4b4)Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff waiting peers.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3selected_index Tff7b72= Te6edf3randomTff7b72.Td2a8ffrandintTb4b4b4(T79c0ff0Tb4b4b4,Tffa657lenTb4b4b4(Te6edf3waiting_peersTb4b4b4)Tff7b72-T79c0ff1Tb4b4b4)
Te6edf3selected_peer Tff7b72= Te6edf3waiting_peersTb4b4b4[Te6edf3selected_indexTb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSelected waiting peer Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3selected_indexTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3selected_peerTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3selected_peerTff7b72.Td2a8ffsyncTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3peer_id Tff7b72in Te6edf3culled_peersTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffRemoving peer Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3peer_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff due to excessive unreachabilityTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3peer_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeersTff7b72.Td2a8ffpopTb4b4b4(Te6edf3peer_idTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while removing peer Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3peer_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72def Td2a8ffpropagation_link_establishedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3linkTff7b72.Td2a8ffset_packet_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_packetTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_strategyTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACCEPT_ALLTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_started_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffresource_transfer_beganTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_resource_concluded_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffpropagation_resource_concludedTb4b4b4)
Tff7b72def Td2a8ffpropagation_packetTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3packetTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3packetTff7b72.Td2a8ffdestination_type Tff7b72!= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffLINKTb4b4b4:
Tff7b72pass
Tff7b72elseTb4b4b4:
Te6edf3data Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3remote_timebase Tff7b72= Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3messages Tff7b72= Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72for Te6edf3lxmf_data Tff7b72in Te6edf3messagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflxmf_propagationTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Te6edf3packetTff7b72.Td2a8ffproveTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while parsing incoming LXMF propagation data.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72def Td2a8ffoffer_requestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3remote_identity Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3LXMPeerTff7b72.Td2a8ffERROR_NO_IDENTITY
Tff7b72elseTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3transient_ids Tff7b72= Te6edf3data
Te6edf3wanted_ids Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3transient_id Tff7b72in Te6edf3transient_idsTb4b4b4:
Tff7b72if Tff7b72not Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4:
Te6edf3wanted_idsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3transient_idTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3wanted_idsTb4b4b4) Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72False
Tff7b72elif Tffa657lenTb4b4b4(Te6edf3wanted_idsTb4b4b4) Tff7b72== Tffa657lenTb4b4b4(Te6edf3transient_idsTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72return Te6edf3wanted_ids
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while generating response for sync request, the contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72None
Tff7b72def Td2a8ffpropagation_resource_concludedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3resourceTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffTransfer concluded for incoming propagation resource Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3resourceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Te6edf3resourceTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffResourceTff7b72.Td2a8ffCOMPLETETb4b4b4:
T8b949e# TODO: The peer this was received from should
T8b949e# have the transient id added to it's list of
T8b949e# already handled messages.
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3resourceTff7b72.Td2a8ffdataTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72if Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Tffa657list Tff7b72and Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== T79c0ff2 Tff7b72and Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Tffa657floatTb4b4b4) Tff7b72and Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72== Tffa657listTb4b4b4:
T8b949e# This is a series of propagation messages from a peer or originator
Te6edf3remote_timebase Tff7b72= Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3remote_hash Tff7b72= Tff7b72None
Te6edf3remote_identity Tff7b72= Te6edf3resourceTff7b72.Td2a8fflinkTff7b72.Td2a8ffget_remote_identityTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3remote_identity Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3remote_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpropagationTa5d6ff"Tb4b4b4)
Te6edf3remote_hash Tff7b72= Te6edf3remote_destinationTff7b72.Td2a8ffhash
Tff7b72if Tff7b72not Te6edf3remote_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffautopeer Tff7b72and Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhops_toTb4b4b4(Te6edf3remote_hashTb4b4b4) Tff7b72<Tff7b72= Tff7b72selfTff7b72.Td2a8ffautopeer_maxdepthTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffpeerTb4b4b4(Te6edf3remote_hashTb4b4b4, Te6edf3remote_timebaseTb4b4b4)
Te6edf3messages Tff7b72= Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72for Te6edf3lxmf_data Tff7b72in Te6edf3messagesTb4b4b4:
Tff7b72if Te6edf3remote_hash Tff7b72!= Tff7b72None Tff7b72and Te6edf3remote_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3transient_id Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3remote_hashTb4b4b4]
Te6edf3peerTff7b72.Td2a8ffhandled_messagesTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Tb4b4b4[Te6edf3transient_idTb4b4b4, Te6edf3remote_timebaseTb4b4b4, Te6edf3lxmf_dataTb4b4b4]
Tff7b72selfTff7b72.Td2a8fflxmf_propagationTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInvalid data structure received at propagation destination, ignoringTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while unpacking received propagation resourceTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72def Td2a8fflxmf_propagationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3lxmf_dataTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3lxmf_dataTb4b4b4) Tff7b72>Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffLXMF_OVERHEADTb4b4b4:
Te6edf3transient_id Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Tff7b72if Tff7b72not Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagation_entries Tff7b72and Tff7b72not Te6edf3transient_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpropagated_idsTb4b4b4:
Te6edf3received Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Te6edf3propagation_entry Tff7b72= Tb4b4b4[Te6edf3transient_idTb4b4b4, Te6edf3receivedTb4b4b4, Te6edf3lxmf_dataTb4b4b4]
Te6edf3destination_hash Tff7b72= Te6edf3lxmf_dataTb4b4b4[Tb4b4b4:Te6edf3LXMessageTff7b72.Td2a8ffDESTINATION_LENGTHTb4b4b4]
Tff7b72if Te6edf3destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffdelivery_destinationsTb4b4b4:
Te6edf3delivery_destination Tff7b72= Tff7b72selfTff7b72.Td2a8ffdelivery_destinationsTb4b4b4[Te6edf3destination_hashTb4b4b4]
Te6edf3encrypted_lxmf_data Tff7b72= Te6edf3lxmf_dataTb4b4b4[Te6edf3LXMessageTff7b72.Td2a8ffDESTINATION_LENGTHTb4b4b4:Tb4b4b4]
Te6edf3decrypted_lxmf_data Tff7b72= Te6edf3delivery_destinationTff7b72.Td2a8ffdecryptTb4b4b4(Te6edf3encrypted_lxmf_dataTb4b4b4)
Te6edf3delivery_data Tff7b72= Te6edf3lxmf_dataTb4b4b4[Tb4b4b4:Te6edf3LXMessageTff7b72.Td2a8ffDESTINATION_LENGTHTb4b4b4]Tff7b72+Te6edf3decrypted_lxmf_data
Tff7b72selfTff7b72.Td2a8fflxmf_deliveryTb4b4b4(Te6edf3delivery_dataTb4b4b4, Te6edf3delivery_destinationTff7b72.Td2a8fftypeTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflocally_delivered_transient_idsTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffpropagation_nodeTb4b4b4:
Te6edf3file_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessagepathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3transient_idTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3receivedTb4b4b4)
Te6edf3msg_file Tff7b72= Tffa657openTb4b4b4(Te6edf3file_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4)
Te6edf3msg_fileTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3lxmf_dataTb4b4b4)
Te6edf3msg_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpropagation_entriesTb4b4b4[Te6edf3transient_idTb4b4b4] Tff7b72= Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3file_pathTb4b4b4, Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657lenTb4b4b4(Te6edf3lxmf_dataTb4b4b4)Tb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffReceived propagated LXMF message Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3transient_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, adding to peer distribution queues...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72for Te6edf3peer_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72selfTff7b72.Td2a8ffpeersTb4b4b4[Te6edf3peer_idTb4b4b4]
Te6edf3peerTff7b72.Td2a8ffhandle_messageTb4b4b4(Te6edf3transient_idTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72return Tff7b72False
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not assemble propagated LXMF message from received dataTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Tff7b72False
Tff7b72def Td2a8fffail_messageTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3lxmessageTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff failed to sendTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpending_outboundTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72selfTff7b72.Td2a8fffailed_outboundTff7b72.Td2a8ffappendTb4b4b4(Te6edf3lxmessageTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72= Te6edf3LXMessageTff7b72.Td2a8ffFAILED
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8fffailed_callback Tff7b72!= Tff7b72None Tff7b72and Tffa657callableTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8fffailed_callbackTb4b4b4)Tb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8fffailed_callbackTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72def Td2a8ffprocess_outboundTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sender Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffprocessing_outboundTb4b4b4:
Tff7b72return
Tff7b72for Te6edf3lxmessage Tff7b72in Tff7b72selfTff7b72.Td2a8ffpending_outboundTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffDELIVEREDTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDelivery has occurred for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, removing from outbound queueTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpending_outboundTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72elif Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffSENTTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffPropagation has occurred for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, removing from outbound queueTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffpending_outboundTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffStarting outbound processing for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
T8b949e# Outbound handling for opportunistic messages
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffOPPORTUNISTICTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72<Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4:
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmessageTb4b4b4, Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attemptTb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72+Tff7b72= T79c0ff1
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffOpportunistic delivery attempt Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffMax delivery attempts reached for oppertunistic Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8fffail_messageTb4b4b4(Te6edf3lxmessageTb4b4b4)
T8b949e# Outbound handling for messages transferred
T8b949e# over a direct link to the final recipient
Tff7b72elif Te6edf3lxmessageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffDIRECTTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72<Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4:
Te6edf3delivery_destination_hash Tff7b72= Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhash
Tff7b72if Te6edf3delivery_destination_hash Tff7b72in Tff7b72selfTff7b72.Td2a8ffdirect_linksTb4b4b4:
T8b949e# A link already exists, so we'll try to use it
T8b949e# to deliver the message
Te6edf3direct_link Tff7b72= Tff7b72selfTff7b72.Td2a8ffdirect_linksTb4b4b4[Te6edf3delivery_destination_hashTb4b4b4]
Tff7b72if Te6edf3direct_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72!= Te6edf3LXMessageTff7b72.Td2a8ffSENDINGTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffStarting transfer of Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffset_delivery_destinationTb4b4b4(Te6edf3direct_linkTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffrepresentation Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffRESOURCETb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe transfer of Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is in progress (Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657roundTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffprogressTff7b72*T79c0ff100Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff%Ta5d6ff)Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffWaiting for proof for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff sent as link packetTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elif Te6edf3direct_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffCLOSEDTb4b4b4:
Tff7b72if Te6edf3direct_linkTff7b72.Td2a8ffactivated_at Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was closedTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmessageTb4b4b4, Ta5d6ff"Ta5d6ffpath_request_retriedTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was never activated, retrying path request...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffpath_request_retried Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was never activatedTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffPATH_REQUEST_WAIT
Te6edf3lxmessageTff7b72.Td2a8ffset_delivery_destinationTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdirect_linksTff7b72.Td2a8ffpopTb4b4b4(Te6edf3delivery_destination_hashTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT
Tff7b72elseTb4b4b4:
T8b949e# Simply wait for the link to become
T8b949e# active or close
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is pending, waiting for link to become activeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
T8b949e# No link exists, so we'll try to establish one, but
T8b949e# only if we've never tried before, or the retry wait
T8b949e# period has elapsed.
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmessageTb4b4b4, Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attemptTb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72+Tff7b72= T79c0ff1
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72< Te6edf3LXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4:
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEstablishing link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for delivery attempt Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3delivery_link Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3delivery_linkTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffprocess_outboundTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdirect_linksTb4b4b4[Te6edf3delivery_destination_hashTb4b4b4] Tff7b72= Te6edf3delivery_link
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNo path known for delivery attempt Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. Requesting path...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffPATH_REQUEST_WAIT
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffMax delivery attempts reached for direct Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8fffail_messageTb4b4b4(Te6edf3lxmessageTb4b4b4)
T8b949e# Outbound handling for messages transported via
T8b949e# propagation to a LXMF router network.
Tff7b72elif Te6edf3lxmessageTff7b72.Td2a8ffmethod Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffPROPAGATEDTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAttempting propagated delivery for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_node Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNo outbound propagation node specified for propagated Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8fffail_messageTb4b4b4(Te6edf3lxmessageTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72<Tff7b72= Te6edf3LXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72!= Tff7b72NoneTb4b4b4:
T8b949e# A link already exists, so we'll try to use it
T8b949e# to deliver the message
Tff7b72if Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffstate Tff7b72!= Te6edf3LXMessageTff7b72.Td2a8ffSENDINGTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffStarting propagation transfer of Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff via Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffset_delivery_destinationTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffsendTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffrepresentation Tff7b72== Te6edf3LXMessageTff7b72.Td2a8ffRESOURCETb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe transfer of Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is in progress (Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657roundTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffprogressTff7b72*T79c0ff100Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff%Ta5d6ff)Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffWaiting for proof for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff sent as link packetTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffCLOSEDTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was closedTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Tff7b72None
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT
Tff7b72elseTb4b4b4:
T8b949e# Simply wait for the link to become
T8b949e# active or close
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe propagation link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is pending, waiting for link to become active: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_linkTff7b72.Td2a8ffstatusTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
T8b949e# No link exists, so we'll try to establish one, but
T8b949e# only if we've never tried before, or the retry wait
T8b949e# period has elapsed.
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmessageTb4b4b4, Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4) Tff7b72or Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attemptTb4b4b4:
Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72+Tff7b72= T79c0ff1
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffDELIVERY_RETRY_WAIT
Tff7b72if Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attempts Tff7b72< Te6edf3LXMRouterTff7b72.Td2a8ffMAX_DELIVERY_ATTEMPTSTb4b4b4:
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEstablishing link to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff for propagation attempt Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3propagation_node_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)
Te6edf3propagation_node_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3propagation_node_identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpropagationTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_link Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4(Te6edf3propagation_node_destinationTb4b4b4, Te6edf3established_callbackTff7b72=Tff7b72selfTff7b72.Td2a8ffprocess_outboundTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffNo path known for propagation attempt Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffdelivery_attemptsTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. Requesting path...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Tff7b72selfTff7b72.Td2a8ffoutbound_propagation_nodeTb4b4b4)
Te6edf3lxmessageTff7b72.Td2a8ffnext_delivery_attempt Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3LXMRouterTff7b72.Td2a8ffPATH_REQUEST_WAIT
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffMax delivery attempts reached for propagated Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3lxmessageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffget_destinationTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8fffail_messageTb4b4b4(Te6edf3lxmessageTb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────